跳到主要内容

gf 路由管理

规范路由

package main

import (
"context"
"fmt"

"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)

type HelloReq struct {
g.Meta `path:"/hello" method:"get"`
Name string `v:"required" dc:"Your name"`
}
type HelloRes struct {
Reply string `dc:"Reply content"`
}

type Hello struct{}

func (Hello) Say(ctx context.Context, req *HelloReq) (res *HelloRes, err error) {
g.Log().Debugf(ctx, `receive say: %+v`, req)
res = &HelloRes{
Reply: fmt.Sprintf(`Hi %s`, req.Name),
}
return
}

func main() {
s := g.Server()
s.Use(ghttp.MiddlewareHandlerResponse)
s.Group("/", func(group *ghttp.RouterGroup) {
group.Bind(
new(Hello),
)
})
s.Run()
}

Tag 编写参考文档:接口文档-OpenAPIv3

提示

注意下面的 pparams 的缩写,更简洁,主要用于请求参数到结构体属性的映射转换,参考文档 对象信息-gstructs

type RuleUpdateReq struct {
g.Meta `path:"/menu/update" tags:"菜单管理" method:"put" summary:"修改菜单"`
Authorization string `p:"Authorization" in:"header" dc:"Bearer {{token}}"`
Id uint `p:"id" v:"required#id必须"`
MenuType uint `p:"menuType" v:"min:0|max:2#菜单类型最小值为:min|菜单类型最大值为:max"`
Pid uint `p:"parentId" v:"min:0"`
Name string `p:"name" v:"required#请填写规则名称"`
Title string `p:"menuName" v:"required|length:1,100#请填写标题|标题长度在:min到:max位"`
Icon string `p:"icon"`
Weigh int `p:"menuSort" `
Condition string `p:"condition" `
Remark string `p:"remark" `
IsHide uint `p:"isHide"`
Path string `p:"path"`
Redirect string `p:"redirect"` // 路由重定向
Roles []uint `p:"roles"` // 角色ids
Component string `p:"component" v:"required-if:menuType,1#组件路径不能为空"`
IsLink uint `p:"isLink"`
IsIframe uint `p:"isIframe"`
IsCached uint `p:"isKeepAlive"`
IsAffix uint `p:"isAffix"`
LinkUrl string `p:"linkUrl"`
}

写标准路由首先要写请求结构体与响应结构体,对 api 请求与响应接口进行描述。先来看代码模板里的请求结构体:

20221020104428

summary:接口详情描述

summary 是 api 执行的动作描述,说明 api 做了什么动作。

请看上图,通知管理下有4个api,分别是增删改查。 NoticeAdd 函数做的工作是新增通知,那么它的summary推荐的写法是“新增”; NoticePut 函数做的工作是修改通知,那么它的summary推荐的写法是“修改”;

path:路由名

path 是 api 的路由名。但不推荐在请求结构体里写 path,具体原因有下面两条:

1、是在请求结构体里写 path 很容易造成路由冲突。假设某个函数的请求结构体的路由是 /get,另一个函数在路由表中也是 /get,若它们在同一级路由下(假设都在 /api 下)就会造成路由冲突,造成项目启动失败。 2、是 path 分散在不同的请求结构体中写,以后修改起来很麻烦,可维护性差。

dc:内容描述

在 dc 中的内容会被展示在 /swagger 的数据属性栏中。

20221020104727

in:参数来源

path,表示参数从 url 获得

// e.g. localhost:8199/notice/get/1
type NoticeGetReq struct {
g.Meta `summary:"获取" tags:"通知管理"`
NoticeId uint `json:"noticeId" in:"path" dc:"通知id"
}

query,表示参数是 url 后面的 ? 键值对获得

// e.g. localhost:8199/notice/get?noticeId=1
type NoticeGetReq struct {
g.Meta `summary:"获取" tags:"通知管理"`
NoticeId uint `json:"noticeId" in:"query" dc:"通知id"
}

数据校验

文档 数据校验-校验规则

响应结构体

type HelloRes struct {
g.Meta `mime:"text/html" example:"string"`
}

References